<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>MapLibre + deck.gl 渲染LineLayer</title>
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
    <script src="https://unpkg.com/maplibre-gl@3.3.1/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@3.3.1/dist/maplibre-gl.css" rel="stylesheet" />
    <script src="https://unpkg.com/deck.gl@8.9.33/dist.min.js"></script>
    <style>
        body {
            margin: 0;
            padding: 0;
        }

        #map {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
        }

        .controls {
            position: absolute;
            top: 10px;
            right: 10px;
            background: white;
            padding: 10px;
            border-radius: 5px;
            box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
            font-family: Arial, sans-serif;
            font-size: 12px;
        }

        .legend {
            position: absolute;
            bottom: 20px;
            left: 20px;
            background: white;
            padding: 10px;
            border-radius: 5px;
            box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
            font-family: Arial, sans-serif;
            font-size: 12px;
        }
    </style>
</head>

<body>
    <div id="map"></div>
    <div class="controls">
        <button id="add-lines">添加10,000条线</button>
        <div id="line-count">当前线条数量: 0</div>
        <div>
            <label>线宽: <input type="range" id="line-width" min="1" max="10" value="3"></label>
        </div>
        <div>
            <label>透明度: <input type="range" id="opacity" min="0" max="100" value="80"></label>
        </div>
    </div>
    <div class="legend">
        <h3>道路类型</h3>
        <div>
            <div style="display: inline-block; width: 20px; height: 2px; background: rgba(255, 0, 0, 0.8);"></div> 高速公路
        </div>
        <div>
            <div style="display: inline-block; width: 20px; height: 2px; background: rgba(255, 165, 0, 0.8);"></div> 主干道
        </div>
        <div>
            <div style="display: inline-block; width: 20px; height: 2px; background: rgba(0, 0, 255, 0.8);"></div> 次干道
        </div>
        <div>
            <div style="display: inline-block; width: 20px; height: 2px; background: rgba(128, 128, 128, 0.8);"></div>
            支路
        </div>
    </div>

    <script>
        // 天地图API密钥（替换为你自己的）
        const TIANDITU_KEY = "24f053f3d41f3e2df373d25ed9d8fef7";

        // 存储所有线条数据
        let allLines = [];
        let lineCount = 0;

        // 初始化MapLibre地图
        const map = window.map = new maplibregl.Map({
            container: 'map',
            style: {
                version: 8,
                name: '天地图影像',
                sources: {
                    'tdt-img': {
                        type: 'raster',
                        tiles: [
                            `https://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${TIANDITU_KEY}`
                        ],
                        tileSize: 256,
                        attribution: '<a href="https://www.tianditu.gov.cn" target="_blank">天地图</a>'
                    }
                },
                layers: [{
                    id: 'tdt-img-layer',
                    type: 'raster',
                    source: 'tdt-img',
                    minzoom: 0,
                    maxzoom: 18
                }]
            },
            center: [116.3956, 39.9152], // 北京
            zoom: 9
        });

        // 等待地图加载完成
        map.on('load', () => {
            // 创建空的线条图层

            let lineLayer = new deck.LineLayer({
                id: 'line-layer',
                data: allLines,
                pickable: true,
                widthUnits: 'pixels',
                widthScale: 1,
                widthMinPixels: 1,
                getSourcePosition: d => d.from,
                getTargetPosition: d => d.to,
                getColor: d => d.color,
                getWidth: d => d.width,
                // 优化：使用GPU加速
                fp64: false,
                // 交互设置
                autoHighlight: true,
                highlightColor: [255, 255, 255, 255]
            });

            // 创建MapLibreLayer并添加到地图
            const deckLayer = new deck.MapboxOverlay({
                id: 'deck-layer',
                layers: [lineLayer],
                map: map
            });

            map.addControl(deckLayer);

            // 添加交互：点击显示线条信息
            map.on('click', 'deck-layer', (e) => {
                if (e.features && e.features.length > 0) {
                    const feature = e.features[0];
                    new maplibregl.Popup()
                        .setLngLat(e.lngLat)
                        .setHTML(`
              <div><strong>ID:</strong> ${feature.properties.id}</div>
              <div><strong>类型:</strong> ${feature.properties.type}</div>
              <div><strong>长度:</strong> ${feature.properties.length.toFixed(2)} km</div>
            `)
                        .addTo(map);
                }
            });

            // 添加线条按钮事件
            document.getElementById('add-lines').addEventListener('click', () => {
                // 生成10,000条随机线
                const newLines = generateRandomLines(10000, lineCount);
                allLines = [...allLines, ...newLines];
                lineCount += 10000;

                // 更新计数显示
                document.getElementById('line-count').textContent =
                    `当前线条数量: ${lineCount.toLocaleString()}`;

                // 更新图层数据
                lineLayer = lineLayer.clone({
                    data: allLines
                });

                deckLayer.setProps({
                    layers: [lineLayer]
                });
            });

            // 线宽滑块事件
            document.getElementById('line-width').addEventListener('input', (e) => {
                const width = parseInt(e.target.value);
                lineLayer = lineLayer.clone({
                    widthScale: width
                });
                deckLayer.setProps({
                    layers: [lineLayer]
                });
            });

            // 透明度滑块事件
            document.getElementById('opacity').addEventListener('input', (e) => {
                const opacity = parseInt(e.target.value) / 100;
                lineLayer = lineLayer.clone({
                    opacity: opacity
                });
                deckLayer.setProps({
                    layers: [lineLayer]
                });
            });
        });

        // 生成随机线条数据
        function generateRandomLines(count, startId) {
            const lines = [];
            const roadTypes = [{
                    name: '高速公路',
                    color: [255, 0, 0, 200],
                    width: 6
                },
                {
                    name: '主干道',
                    color: [255, 165, 0, 200],
                    width: 4
                },
                {
                    name: '次干道',
                    color: [0, 0, 255, 200],
                    width: 3
                },
                {
                    name: '支路',
                    color: [128, 128, 128, 200],
                    width: 2
                }
            ];

            for (let i = 0; i < count; i++) {
                const id = startId + i;
                const typeIndex = Math.floor(Math.random() * roadTypes.length);
                const type = roadTypes[typeIndex];

                // 随机起点
                const fromLng = 116.1 + Math.random() * 0.6;
                const fromLat = 39.7 + Math.random() * 0.6;

                // 随机终点（距离起点不超过0.05度）
                const toLng = fromLng + (Math.random() - 0.5) * 0.1;
                const toLat = fromLat + (Math.random() - 0.5) * 0.1;

                // 计算近似距离（简化版）
                const dx = (toLng - fromLng) * 111; // 经度差转公里
                const dy = (toLat - fromLat) * 111; // 纬度差转公里
                const length = Math.sqrt(dx * dx + dy * dy);

                lines.push({
                    id,
                    from: [fromLng, fromLat],
                    to: [toLng, toLat],
                    properties: {
                        id,
                        type: type.name,
                        length
                    },
                    color: type.color,
                    width: type.width
                });
            }

            return lines;
        }
    </script>
</body>

</html>